﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlServerCe;

namespace eWallet.Data.Local.eWalletDataSetTableAdapters
{
	public partial class SecretsTableAdapter
	{

		/// <summary>
		/// Creates a new instance of the table adapter and specifies the full file
		/// path to the SQL Server Compact Edition database to connect to.
		/// </summary>
		/// <param name="dbPath">The full file path to the database file.</param>
		public SecretsTableAdapter(string dbPath)
		{
			this._connection = new SqlCeConnection(string.Format("Data Source={0}", dbPath));
		}



		/// <summary>
		/// Fills the given table with the secret with the given ID.
		/// </summary>
		/// <param name="table">The table to fill.</param>
		/// <param name="id">The ID of the secret to fill the table with.</param>
		/// <returns>Returns the number of rows filled.</returns>
		public int Fill(eWalletDataSet.SecretsDataTable table, Guid id)
		{
			if (null == table)
			{
				throw new ArgumentNullException("table");
			}

			int i = 0;

			if (this.ClearBeforeFill)
			{
				table.Clear();
			}

			using (SqlCeCommand cmd = new SqlCeCommand("SELECT * FROM  [Secrets] WHERE [Id] = @Id", this.Connection))
			{
				cmd.Parameters.AddWithValue("@Id", id);

				using (SqlCeDataAdapter adr = new SqlCeDataAdapter(cmd))
				{
					i = adr.Fill(table);
				}
			}

			return i;
		}

		/// <summary>
		/// Returns a table with the secret with the given ID.
		/// </summary>
		/// <param name="id">The ID of the secret to return.</param>
		public eWalletDataSet.SecretsDataTable GetData(Guid id)
		{
			eWalletDataSet.SecretsDataTable tbl = new eWalletDataSet.SecretsDataTable();
			this.Fill(tbl, id);
			return tbl;
		}

		
		/// <summary>
		/// Sets the tags for the given secret. Any previous tags are replaced.
		/// </summary>
		/// <param name="secretId">The id of the secret whose tags to set.</param>
		/// <param name="tags">The tags to set on the given secret. If this collection is empty or null, any existing tags on the given secret will be erased.</param>
		public void SetTags(Guid secretId, IEnumerable<string> tags)
		{
			using (SqlCeConnection conn = new SqlCeConnection(this.Connection.ConnectionString))
			{
				conn.Open();
				using (SqlCeCommand cmd = new SqlCeCommand("DELETE FROM [SecretsTags] WHERE [SecretId] = @SecretId", conn))
				{
					cmd.Parameters.AddWithValue("@SecretId", secretId);
					cmd.ExecuteNonQuery();
				}

				foreach (string tag in tags)
				{
					int i = 0;
					Guid tagId;
					using (SqlCeCommand cmd = new SqlCeCommand("SELECT COUNT(*) FROM [Tags] WHERE [Label] = @Tag", conn))
					{
						cmd.Parameters.AddWithValue("@Tag", tag);
						i = (int)cmd.ExecuteScalar();
					}
					if (i == 0)
					{
						using (SqlCeCommand cmd = new SqlCeCommand("INSERT INTO [Tags]([Id], [Label]) VALUES(NEWID(), @Tag)", conn))
						{
							cmd.Parameters.AddWithValue("@Tag", tag);
							cmd.ExecuteNonQuery();
						}
					}

					using (SqlCeCommand cmd = new SqlCeCommand("SELECT [Id] FROM [Tags] WHERE [Label] = @Tag", conn))
					{
						cmd.Parameters.AddWithValue("@Tag", tag);
						tagId = (Guid)cmd.ExecuteScalar();
					}

					using(SqlCeCommand cmd = new SqlCeCommand("SELECT COUNT(*) FROM [Secrets] WHERE [Id] = @Id", conn))
					{
						cmd.Parameters.AddWithValue("@Id", secretId);
						i = (int)cmd.ExecuteScalar();
					}

					if (i > 0)
					{
						using (SqlCeCommand cmd = new SqlCeCommand("INSERT INTO [SecretsTags]([SecretId], [TagId]) VALUES(@SecretId, @TagId)", conn))
						{
							cmd.Parameters.AddWithValue("@SecretId", secretId);
							cmd.Parameters.AddWithValue("@TagId", tagId);
							cmd.ExecuteNonQuery();
						}
					}
				}
				
				using (SqlCeCommand cmd = new SqlCeCommand("DELETE FROM [Tags] WHERE [Id] NOT IN (SELECT [TagId] FROM [SecretsTags])", conn))
				{
					cmd.ExecuteNonQuery();
				}
			}
		}

		/// <summary>
		/// Sets the tags for the given secret. Any previous tags are replaced.
		/// </summary>
		/// <param name="secretId">The id of the secret whose tags to set.</param>
		/// <param name="tags">The tags to set on the given secret. If this array is empty or null, any existing tags on the given secret will be erased.</param>
		public void SetTags(Guid secretId, params string[] tags)
		{
			this.SetTags(secretId, (IEnumerable<string>)tags);
		}

	}
}
